package znet

import (
	"fmt"
	"sync"
	"sync/atomic"

	"zinx-tianjing-study/ziface"
)

// MessageHandleConfig 消息处理器配置
type MessageHandleConfig struct {
	WorkerPoolSize uint32
	TaskQueueSize  uint32
	DebugMode      bool
}

// DefaultConfig 默认配置
var DefaultConfig = MessageHandleConfig{
	WorkerPoolSize: 10,
	TaskQueueSize:  1024,
	DebugMode:      true,
}

type MessageHandle struct {
	Apis           map[uint32]ziface.IRouter
	Lock           sync.RWMutex
	apiCount       int32
	debugMode      bool
	TaskQueue      []chan ziface.IRequest
	WorkerPoolSize uint32
	TaskQueueSize  uint32
	currentID      uint32
}

// NewMessageHandle 创建一个新的 MessageHandle 实例
func NewMessageHandle(config *MessageHandleConfig) *MessageHandle {
	if config == nil {
		config = &DefaultConfig
	}

	m := &MessageHandle{
		Apis:           make(map[uint32]ziface.IRouter),
		Lock:           sync.RWMutex{},
		debugMode:      config.DebugMode,
		WorkerPoolSize: config.WorkerPoolSize,
		TaskQueueSize:  config.TaskQueueSize,
	}

	m.initWorkerPool()
	return m
}

// initWorkerPool 初始化工作池
func (m *MessageHandle) initWorkerPool() {
	m.TaskQueue = make([]chan ziface.IRequest, m.WorkerPoolSize)

	// 初始化并启动所有worker
	for i := uint32(0); i < m.WorkerPoolSize; i++ {
		m.TaskQueue[i] = make(chan ziface.IRequest, m.TaskQueueSize)
		m.logDebug("初始化 workerID=%d 的 task queue", i)
		go m.startWorker(i)
		m.logDebug("启动 workerID=%d 协程", i)
	}
}

// logDebug 日志输出辅助函数
func (m *MessageHandle) logDebug(format string, args ...interface{}) {
	if m.debugMode {
		fmt.Printf("[DEBUG] "+format+"\n", args...)
	}
}

// DoMessageHandle 执行对应的消息处理逻辑
func (m *MessageHandle) DoMessageHandle(r ziface.IRequest) {
	msgID := r.GetMsgID()

	router, ok := m.getRouter(msgID)
	if !ok {
		m.logDebug("当前消息ID未注册，无法处理：msgID=%d", msgID)
		return
	}

	m.logDebug("开始处理消息ID=%d", msgID)
	defer m.logDebug("消息ID=%d 已处理完毕", msgID)

	// 执行路由中的处理流程
	m.executeRouter(router, r)
}

// getRouter 获取路由处理器
func (m *MessageHandle) getRouter(msgID uint32) (ziface.IRouter, bool) {
	m.Lock.RLock()
	defer m.Lock.RUnlock()
	router, ok := m.Apis[msgID]
	return router, ok
}

// executeRouter 执行路由处理流程
func (m *MessageHandle) executeRouter(router ziface.IRouter, r ziface.IRequest) {
	defer func() {
		if err := recover(); err != nil {
			m.logDebug("路由处理发生panic: %v", err)
		}
	}()

	router.PreHandle(r)
	router.Handle(r)
	router.PostHandle(r)
}

// AddRouter 添加一个消息路由
func (m *MessageHandle) AddRouter(msgID uint32, router ziface.IRouter) {
	m.Lock.Lock()
	defer m.Lock.Unlock()

	if router == nil {
		m.logDebug("router 不能为空")
		return
	}

	if _, ok := m.Apis[msgID]; ok {
		m.logDebug("当前消息ID已注册: %d", msgID)
		return
	}

	m.Apis[msgID] = router
	atomic.AddInt32(&m.apiCount, 1)
	m.logDebug("添加消息ID成功：%d", msgID)
}

// GetApiCount 获取当前注册的API数量
func (m *MessageHandle) GetApiCount() int {
	m.Lock.RLock()
	defer m.Lock.RUnlock()
	return int(m.apiCount)
}

// SetDebugMode 设置是否启用调试模式
func (m *MessageHandle) SetDebugMode(enable bool) {
	m.debugMode = enable
}

// SubmitTask 将 IRequest 提交到 TaskQueue 中
func (m *MessageHandle) SubmitTask(r ziface.IRequest) error {
	if r == nil {
		return fmt.Errorf("request 不能为空")
	}

	// 获取当前 worker id（轮询）
	curID := atomic.AddUint32(&m.currentID, 1) % m.WorkerPoolSize

	select {
	case m.TaskQueue[curID] <- r:
		return nil
	default:
		return fmt.Errorf("task queue %d 已满", curID)
	}
}

// startWorker 启动单个 worker 协程
func (m *MessageHandle) startWorker(workerID uint32) {
	m.logDebug("WorkerID=%d 开始监听任务...", workerID)

	for task := range m.TaskQueue[workerID] {
		if task == nil {
			continue
		}

		msgID := task.GetMsgID()
		m.logDebug("WorkerID=%d 接收任务: 消息ID=%d", workerID, msgID)

		m.DoMessageHandle(task)

		m.logDebug("WorkerID=%d 完成任务: 消息ID=%d", workerID, msgID)
	}
}
